package com.lcy.web.generator;

import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.c3p0.C3p0Plugin;

import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Scanner;

/**
 * GeneratorDemo
 * 从数据库生成 Model
 */
public class ModelGenerator {
    private static final String DEFAULT_GENERATOR_CONFIG_FILE_PATH = "res/generator/SqlModel.properties";
    private static final String SOURCE_CODE_PATH_IN_MODEL = "/src/main/java";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        String[] strings = null;
        URL url = ModelGenerator.class.getClassLoader().getResource(DEFAULT_GENERATOR_CONFIG_FILE_PATH);
        String path = url.getPath();
        path = getInputUseDefault(scanner, "使用默认配置文件(resources/res/generator/SqlModel.properties) : " + path + " ？（y/n）", "输入配置文件路径 : ", path);
        strings = getParamsFromFile(path, scanner);


        String jdbcUrl = strings[0];
        String user = strings[1];
        String password = strings[2];
        String baseModelPackageName = strings[3];
        String modelPackageName = strings[4];
        String baseModelOutputDir = strings[5];
        String modelOutputDir = strings[6];
        String tablePrefix = strings[7];

        C3p0Plugin c3p0Plugin = new C3p0Plugin(jdbcUrl, user, password);
        c3p0Plugin.start();

        System.out.println("BaseModel 输出路径 : " + baseModelOutputDir);
        System.out.println("Model 输出路径 : " + modelOutputDir);
        System.out.println("JDBC URL : " + jdbcUrl);
        System.out.println("user : " + user);
        System.out.println("password : " + password);

        // 创建生成器
        Generator generator = new MyGenerator(c3p0Plugin.getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
        // 设置数据库方言
        generator.setDialect(new MysqlDialect());
        // 添加不需要生成的表名
        generator.addExcludedTable("adv");
        // 设置是否在 Model 中生成 dao 对象
        generator.setGenerateDaoInModel(true);
        // 设置是否生成字典文件
        generator.setGenerateDataDictionary(false);
        // 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user"，移除前缀 "osc_"后生成的model名为 "User"而非 OscUser
        if (tablePrefix != null && tablePrefix.length() > 0) {
            generator.setRemovedTableNamePrefixes(tablePrefix);
        }
        // 生成
        generator.generate();
        c3p0Plugin.stop();
    }

    /**
     * 从 scanner 获取输入值
     *
     * @param scanner scanner
     * @param hint    输入提示
     * @return 用户输入
     */
    private static String getInput(Scanner scanner, String hint) {
        System.out.println(hint);
        return scanner.next().trim();
    }

    /**
     * @param scanner      scanner
     * @param hint         输入提示
     * @param inputHint    不使用默认值时的提示
     * @param defaultValue 默认值
     * @return 用户输入的值或默认值
     */
    private static String getInputUseDefault(Scanner scanner, String hint, String inputHint, String defaultValue) {
        System.out.println(hint);
        String b = scanner.next().trim();
        if (b.equals("y") || b.equals("Y")) {
            return defaultValue;
        } else {
            System.out.println(inputHint);
            return scanner.next().trim();
        }
    }

    /**
     * @return 获取当前类所在包名
     */
    private static String getPackageName() {
        return ModelGenerator.class.getPackage().getName();
    }

    /**
     * baseModel 在 model 包下一级
     *
     * @return baseModel 包名
     */
    private static String getBaseModelPackageName() {
        return getModelPackageName() + ".base";
    }

    /**
     * Model 包和当前类所在包平级
     *
     * @return model 包名
     */
    private static String getModelPackageName() {
        String packageName = getPackageName();
        int index = packageName.lastIndexOf(".") + 1;
        return packageName.substring(0, index) + "model";
    }

    /**
     * @return 工程路径
     */
    private static String getProjectPath() {
        return System.getProperty("user.dir");
    }

    /**
     * 包名转换为路径
     * param name 包名
     *
     * @return 路径
     */
    private static String packageNameToPath(String name) {
        return File.separator + name.replace('.', File.separatorChar);
    }

    /**
     * 从文件获取配置选项
     *
     * @param path    配置文件路径
     * @param scanner scanner
     * @return 配置参数
     */
    private static String[] getParamsFromFile(String path, Scanner scanner) {
        File file = new File(path);
        if (!file.exists()) {
            throw new RuntimeException("配置文件不存在");
        }

        Prop prop = PropKit.use(file);

        String[] keys = {
                "jdbcUrl",
                "user",
                "password",
                "baseModelPackageName",
                "modelPackageName",
                "baseModelOutputDir",
                "modelOutputDir",
                "tablePrefix"};
        String[] strings = new String[keys.length];
        for (int i = 0; i < keys.length; i++) {
            strings[i] = prop.get(keys[i]);
        }
        String moduleName = prop.get("moduleName");
        String modulePath = null;
        if (moduleName == null) {
            modulePath = SOURCE_CODE_PATH_IN_MODEL.replace('/', File.separatorChar);
        } else {
            modulePath = File.separator + moduleName + SOURCE_CODE_PATH_IN_MODEL.replace('/', File.separatorChar);
        }

        // base model 文件保存路径
        if (strings[5] == null) {
            strings[5] = getProjectPath() + modulePath + packageNameToPath(strings[3]);
        }
        if (strings[6] == null) {
            strings[6] = getProjectPath() + modulePath + packageNameToPath(strings[4]);
        }

        for (int i = 0; i < strings.length; i++) {
            if (strings[i] == null || strings[i].isEmpty()) {
                if (i != 7) {
                    throw new RuntimeException("配置文件缺少必须的参数");
                }
            }
        }

        return strings;
    }
}




